/*
 * @Author: xiaosihan 
 * @Date: 2023-02-06 15:22:57 
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2024-05-29 16:05:20
 */
import { AmbientLight, Color, DirectionalLight, DisplayP3ColorSpace, Fog, LinearDisplayP3ColorSpace, LinearSRGBColorSpace, Matrix4, NoColorSpace, PointLight, SRGBColorSpace, Vector3 } from "three";
import ThreeBase from "three-base";
import FloorGrid from "./component3d/Grid/Grid";
import BeijingMap from "./component3d/BeijingMap/BeijingMap";
import HtmlLableReflextion from "./component3d/HtmlLableReflextion/HtmlLableReflextion";
import keyContorls from "three-base/keyContorls";
import { round, transform } from "lodash";
import homeStore from "./homeStore";
import threeLoader from "three-base/threeLoader";

/**
 * @class HomeRender
 * @extends {ThreeBase}
 */
class HomeRender extends ThreeBase {

    constructor() {
        super();
    }

    // 环境光
    ambientLight = (() => {
        const ambientLight = new AmbientLight(0xffffff, 3);
        this.scene.add(ambientLight);
        return ambientLight;
    })();

    //点光源1
    pointLight1 = (() => {
        const pointLight = new PointLight("#1d5e5e", 600, 10000);
        pointLight.position.set(-9, 3, -3);
        this.scene.add(pointLight);
        return pointLight;
    })();

    //点光源2
    pointLight2 = (() => {
        const pointLight = new PointLight("#1d5e5e", 230, 10000);
        pointLight.position.set(0, 2, 5);
        this.scene.add(pointLight);
        return pointLight;
    })();

    // // 方向光
    directionalLight = (() => {
        let directionalLight = new DirectionalLight(0xffffff, 8)
        directionalLight.position.set(-30, 6, -8)
        directionalLight.castShadow = true
        directionalLight.shadow.radius = 20
        directionalLight.shadow.mapSize.width = 1024
        directionalLight.shadow.mapSize.height = 1024
        this.scene.add(directionalLight);
        return directionalLight;
    })();

    //地板网格对象
    floorGrid = (() => {
        const floorGrid = new FloorGrid();
        this.scene.add(floorGrid);
        return floorGrid;
    })();

    //北京地图
    beijingMap = (() => {
        const beijingMap = new BeijingMap();
        this.scene.add(beijingMap);
        return beijingMap;
    })();

    epsilon(value: number) {
        return Math.abs(value) < 1e-10 ? 0 : value;
    }

    getCameraCSSMatrix(matrix: Matrix4) {
        const elements = matrix.elements;
        return "matrix3d(" + this.epsilon(elements[0]) + "," + this.epsilon(-elements[1]) + "," + this.epsilon(elements[2]) + "," + this.epsilon(elements[3]) + "," + this.epsilon(elements[4]) + "," + this.epsilon(-elements[5]) + "," + this.epsilon(elements[6]) + "," + this.epsilon(elements[7]) + "," + this.epsilon(elements[8]) + "," + this.epsilon(-elements[9]) + "," + this.epsilon(elements[10]) + "," + this.epsilon(elements[11]) + "," + this.epsilon(elements[12]) + "," + this.epsilon(-elements[13]) + "," + this.epsilon(elements[14]) + "," + this.epsilon(elements[15]) + ")";
    }

    // 获取css3d变换样式
    getCameraCSSTransfrom() {
        const _widthHalf = this.size.x / 2;
        const _heightHalf = this.size.y / 2;
        const fov = this.perspectiveCamera.projectionMatrix.elements[5] * _heightHalf;
        const scaleByViewOffset = 1;
        const cameraCSSMatrix = `scale( ${scaleByViewOffset} )translateZ(` + fov + "px)" + this.getCameraCSSMatrix(this.perspectiveCamera.matrixWorldInverse);
        const cameraCSSTransfrom = cameraCSSMatrix + "translate(" + _widthHalf + "px," + _heightHalf + "px)";
        const perspectiveStyle = { perspective: `${fov}px` };
        return { perspectiveStyle, cameraCSSTransfrom };
    }

    init() {
        super.init();
        this.gridHelper.visible = false; // 隐藏three-base默认设置的网格
        this.scene.fog = new Fog(0x091b21, 1, 500);
        this.scene.background = new Color("#091B21");
        this.renderer.outputColorSpace = SRGBColorSpace;
        //设置相机初始位置
        // this.resetLookAt({
        //     center: new Vector3(-0.095, -0.455, 0.458),
        //     position: new Vector3(-0.24, 9.019, 10.131)
        // });

        this.resetLookAt({
            center: new Vector3(-0.095, -0.455, 0.458),
            position: new Vector3(-15.202, 20.163, 39.18)
        });

        //执行动画
        (async () => {

            // 等待资源加载完成
            while (!threeLoader.onload) {
                await new Promise(resolve => setTimeout(resolve, 50));
                await new Promise(resolve => requestAnimationFrame(resolve));
            }

            this.controlsPosition.setBezier([0.62, 0.22, 0.31, 0.73]);

            //1视角拉进
            this.setLookAt({
                duration: 3000,
                center: new Vector3(-0.095, -0.455, 0.458),
                position: new Vector3(-0.24, 9.019, 10.131)
            });

            await new Promise(resolve => setTimeout(resolve, 2000));

            await this.floorGrid.init();

            await this.beijingMap.init();

            await this.beijingMap.barGroup.init();


        })();


    }

    render() {
        super.render();
        // 获取css3d变换样式
        const { perspectiveStyle, cameraCSSTransfrom } = this.getCameraCSSTransfrom();
        const lable2d_group = document.getElementById("lable2d_group");
        const css3d_camera = document.getElementById("css3d_camera");

        if (lable2d_group && css3d_camera) {
            Object.assign(lable2d_group.style, perspectiveStyle)
            Object.assign(css3d_camera.style, {
                transform: cameraCSSTransfrom
            })
        }

        //如果有选中弹窗,就时时计算选中弹窗位置
        if (homeStore.infoPoint) {
            const { lng, lat } = homeStore.infoPoint;
            //地图偏移量
            const offset = new Vector3(-116.468994140625 * 5, 0, 40.25177764892578 * 5);
            let point = new Vector3(lng, 0.1, -lat).multiplyScalar(5).add(offset);
            const v2 = this.v3tov2(point);
            homeStore.setModalPosition({ x: v2.x, y: v2.y });
        }

    }

}


const homeRenderer = window.homeRenderer = new HomeRender();

export default homeRenderer;